/*
Follow up for "Unique Paths":

Now consider if some obstacles are added to the grids. How many unique paths would there be?

An obstacle and empty space is marked as 1 and 0 respectively in the grid.

For example,
There is one obstacle in the middle of a 3x3 grid as illustrated below.

[
  [0,0,0],
  [0,1,0],
  [0,0,0]
]
The total number of unique paths is 2.
*/

// iterative dynamic programming
class Solution {
public:
    int uniquePathsWithObstacles(vector<vector<int> > &obstacleGrid) {
        int m = obstacleGrid.size();
        int n = obstacleGrid[0].size();
        int npaths[m+1][n+1];
        for (int i = 0; i <= n; i++) npaths[0][i] = 0;
        for (int i = 0; i <= m; i++) npaths[i][0] = 0;
        for (int i = 1; i <= m; i++) {
            for (int j = 1; j <=n; j++) {
                if (obstacleGrid[i-1][j-1]) npaths[i][j] = 0;
                else if (i==1 && j==1) npaths[i][j] = 1;
                else npaths[i][j] = npaths[i-1][j] + npaths[i][j-1];
            }
        }
        return npaths[m][n];
    }
};

// Recursive solution
#if 0
class Solution {
public:
    int _uniquePaths(int curx, int cury, int m, int n, int **v, vector<vector<int> > &matrix) {
        int num = 0;
        // hit the destination
        if (curx == m-1 && cury == n-1) {
            v[m-1][n-1] = 1;
            return 1;
        }
        // move down
        if (curx < m-1 && !matrix[curx+1][cury]) {
            if (v[curx+1][cury]) {
                num += v[curx+1][cury];
            } else {
                num += _uniquePaths(curx+1, cury, m, n, v, matrix);
            }
        }
        // move right
        if (cury < n-1 && !matrix[curx][cury+1]) {
            if (v[curx][cury+1]) {
                num += v[curx][cury+1];
            } else {
                num += _uniquePaths(curx, cury+1, m, n, v, matrix);
            }
        }
        v[curx][cury] = num;
        return num;
    }
    int uniquePathsWithObstacles(vector<vector<int> > &obstacleGrid) {
        int m = obstacleGrid.size();
        int n = obstacleGrid[0].size();
        if (obstacleGrid[0][0] ||
            obstacleGrid[m-1][n-1]) {return 0;}
        int **v = new int * [m];
        for (int i = 0; i< m; i++) {
            v[i] = new int[n];
            for (int j =0; j < n; j++) {
                v[i][j] = 0;
            }
        }
        // start from (0, 0)
        int numpaths = _uniquePaths(0, 0, m, n, v, obstacleGrid);
        for (int i = 0; i< m; i++) {
            delete [] v[i];
        }
        delete [] v;
        return numpaths;
    }
};
#endif
